package com.travel.server.manager.impl.command.project.data;

import com.travel.common.CommonConstant;
import com.travel.common.util.CollectionUtil;
import com.travel.common.util.CommonUtil;
import com.travel.common.util.DateUtil;
import com.travel.server.manager.dto.request.project.data.QueryProjectApplyRequest;
import com.travel.server.manager.dto.response.project.data.QueryProjectApplyResponse;
import com.travel.server.manager.dto.response.project.data.QueryProjectApplyResponse.ApplyItem;
import com.travel.server.manager.dto.response.project.data.QueryProjectApplyResponse.ProjectApplyItem;
import com.travel.server.manager.impl.command.AbstractCommand;
import com.travel.server.manager.impl.dal.OrderDal;
import com.travel.server.manager.impl.dal.ProjectDal;
import com.travel.server.manager.model.dto.data.DayApplyDto;
import com.travel.server.manager.model.dto.data.ProjectApplyDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @Author: LiZhenhui
 * @Date: 2018/11/29 12:13
 * @Desc:
 */
@Component
@Slf4j
public class QueryProjectApplyCommand extends AbstractCommand<QueryProjectApplyRequest, QueryProjectApplyResponse> {

    @Autowired
    private OrderDal orderDal;

    @Autowired
    private ProjectDal projectDal;

    @Override
    protected void checkInput(QueryProjectApplyRequest request) {
        checkTimeInput(request);
    }

    @Override
    public QueryProjectApplyResponse handle(QueryProjectApplyRequest request) {
        checkInput(request);

        QueryProjectApplyResponse response = new QueryProjectApplyResponse();

        Date startTime = DateUtil.getDataTime(request.getStartTime());
        Date endTime = DateUtil.getDataEndTime(request.getEndTime());
        response.setProjectApplyList(makeProjectApply(startTime, endTime, request.getOffset(), request.getLimit()));
        response.setApplyList(makeApply(startTime, endTime));
        response.setTotalNum(projectDal.selectUsefulTotal());

        if(CommonConstant.YES.equals(request.getIsCount())){
            Date today = DateUtil.get(new Date(), 0, 0, 0, 0);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(today);
            calendar.add(Calendar.DAY_OF_MONTH, -1);
            Date yesterday = DateUtil.get(calendar.getTime(), 23, 59, 59, 999);
            List<DayApplyDto> list = orderDal.selectDayApply(today, yesterday);
            if(!CollectionUtil.isEmpty(list)) {
                for (DayApplyDto item : list) {
                    if (DateUtil.isSameDay(item.getTravelDate(), today)){
                        response.setToday(CommonUtil.fenToYuan(item.getApply()).toString());
                    }else if(DateUtil.isSameDay(item.getTravelDate(), yesterday)){
                        response.setYesterday(CommonUtil.fenToYuan(item.getApply()).toString());
                    }
                }
            }
        }else{
            response.setToday(null);
            response.setYesterday(null);
        }

        return response;
    }

    private List<ApplyItem> makeApply(Date startTime, Date endTime){
        List<ApplyItem> applyList = new ArrayList<>();
        Calendar weekCalendar = Calendar.getInstance();
        weekCalendar.setTime(startTime);
        weekCalendar.add(Calendar.DATE, -7);
        Date weekStartTime = weekCalendar.getTime();
        List<DayApplyDto> list = orderDal.selectDayApply(weekStartTime, endTime);
        Map<String, Integer> dayApplyMap = makeProjectProfitMap(list);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startTime);
        while(calendar.getTime().before(endTime) || calendar.getTime().equals(endTime)){
            String key = DateUtil.YYYYMMDD.format(calendar.getTime());
            Integer apply = dayApplyMap.get(key);
            Calendar lastWeek = Calendar.getInstance();
            lastWeek.setTime(calendar.getTime());
            lastWeek.add(Calendar.DATE, -7);
            String lastWeekKey = DateUtil.YYYYMMDD.format(lastWeek.getTime());
            Integer lastWeekApply = dayApplyMap.get(lastWeekKey);
            if(apply == null){
                apply = 0;
            }
            if(lastWeekApply == null){
                lastWeekApply = 0;
            }
            ApplyItem item = new ApplyItem();
            item.setApply(CommonUtil.fenToYuan(apply).toString());
            item.setAdd(CommonUtil.getProportion(apply - lastWeekApply, lastWeekApply));
            item.setDate(calendar.getTime());
            item.setWeekDate(lastWeek.getTime());
            applyList.add(item);
            calendar.add(Calendar.DAY_OF_MONTH, 1);
        }
        return applyList;
    }

    private Map<String, Integer> makeProjectProfitMap(List<DayApplyDto> list){
        Map<String, Integer> map = new HashMap<>();
        for(DayApplyDto item : list){
            map.put(DateUtil.YYYYMMDD.format(item.getTravelDate()), item.getApply());
        }
        return map;
    }


    public List<ProjectApplyItem> makeProjectApply(Date startTime, Date endTime, Integer offset, Integer limit){
        List<ProjectApplyItem> list = new ArrayList<>();
        List<ProjectApplyDto> dtoList = orderDal.selectProjectApply(startTime, endTime, offset, limit);
        if(!CollectionUtil.isEmpty(dtoList)){
            for(ProjectApplyDto dto : dtoList){
                ProjectApplyItem item = new ProjectApplyItem();
                item.setProject(dto.getName());
                item.setApply(dto.getApplyAmount() + "");
                item.setOrder((dto.getOrderCount() + dto.getRefundCount()) + "");
                item.setRefund(dto.getRefundCount() + "");
                item.setIncome(dto.getApplyAmount() * (dto.getOrderCount()) + "");
                list.add(item);
            }
        }
        return list;
    }
}
